<template>
  <div class="home">
    <div class="header">
      <div class="logo"></div>
      <div class="titleMain">
        <h1>单产线成材率分析</h1>
      </div>
    </div>
    <div class="page-layout">
      <div class="head-container">
        <div class="header-img"><img src="/src/assets/images/yield/text-sub.png" alt="" /></div>
        <div class="header-condition">
          <div class="line">
            <div v-for="item in lines" :key="item" class="line-item" :class="headerButtonClass(item)" @click="curLineChange(item)">{{ item }}</div>
          </div>
          <div class="date">
            <div class="buttons">
              <button
                v-for="dateType in dateTypes"
                :key="dateType"
                :class="{ 'is-active': condition.curDateType === dateType }"
                @click="dateTypeClick(dateType)"
              >
                {{ dateType }}
              </button>
            </div>
            <el-date-picker
              v-model="condition.dateRange"
              type="daterange"
              range-separator="至"
              value-format="YYYY-MM-DD"
              class="date-picker"
              @change="dateChange"
            />
          </div>
        </div>
      </div>
      <div class="main-container">
        <div class="area trend-card">
          <div class="title-head">
            <div class="title">
              <img src="/src/assets/images/report/tcm2280/title-icon1.png" />
              <span>成材率趋势图</span>
            </div>
          </div>
          <graph-line
            :datax="graphData.lineData.x"
            :data1="graphData.lineData.y1"
            :min="graphData.lineData.min"
            :max="graphData.lineData.max"
            :data-name="['成材率%']"
          />
        </div>
        <div class="area crew-card">
          <div class="title-head">
            <div class="title">
              <img src="/src/assets/images/report/tcm2280/title-icon1.png" />
              <span>班组成材率统计</span>
            </div>
          </div>
          <graph-bar-line
            :data-bar1="graphData.barData.y1"
            :datax="graphData.barData.x"
            :bar-name="['成材率%']"
            :y-axis-name="['成材率%']"
            :min="graphData.barData.min"
            :max="graphData.barData.max"
            :config="graphData.barData.config"
          />
        </div>
        <div class="area waste-card">
          <div class="title-head">
            <div class="title">
              <img src="/src/assets/images/report/tcm2280/title-icon1.png" />
              <span>坯料判废量(吨)</span>
            </div>
            <div class="buttons" style="height: 2.5vh">
              <button
                style="width: 62px; height: 24px"
                v-for="wasteType in wasteTypes"
                :key="wasteType"
                :class="{ 'is-active': condition.wasteType === wasteType }"
                @click="wasteTypeClick(wasteType)"
              >
                {{ wasteType == 'reason' ? '原因' : '钢种' }}
              </button>
            </div>
          </div>
          <div class="progress" style="margin-top: 19px">
            <div class="progress-container" v-for="(item, index) in wasteInfo">
              <div class="progress-info">
                <span>{{ item.name }}</span>
                <span class="progress-num">{{ item.current }}/{{ item.total }}</span>
              </div>
              <div class="progress-bar">
                <div class="progress-background"></div>
                <div
                  class="progress-inner"
                  :style="{ '--target-width': (Number(item.current) / Number(item.total)) * 100 + '%', animationDelay: index * 0.1 + 0.2 + 's' }"
                ></div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="table-container">
        <el-table
          size="small"
          :data="tableData"
          style="width: 100%"
          max-height="252px"
          :header-cell-style="{ background: '#2f59af', color: '#fff', textAlign: 'center' }"
          :cell-style="{
            color: '#fff',
            textAlign: 'center',
            border: '1px solid #2875A6',
          }"
          show-overflow-tooltip
        >
          <el-table-column prop="steelGrade" label="钢种" />
          <el-table-column prop="exthkSpeci" label="厚度分档" />
          <el-table-column prop="widSpeci" label="宽度分档" />
          <el-table-column prop="targetValue" label="目标值" />
          <el-table-column prop="yield" label="成材率">
            <template #default="{ row }"> {{ (row.yield * 100).toFixed(2) + '%' }} </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
  import { ref, reactive, onMounted } from 'vue';
  import { ElMessage, ElNotification } from 'element-plus';
  import { ActualPerformanceRollDeviationApi } from '/@/api/deviationanalysis/ActualPerformanceRollDeviation';
  import GraphBarLine from '/@/views/FullProcessYieldRate/components/GraphBarLine.vue';
  import GraphLine from '/@/views/FullProcessYieldRate/components/GraphLine.vue';
  import dayjs from 'dayjs';

  type WasteType = 'reason' | 'steelGrade';

  interface Condition {
    curDateType: DateType;
    dateRange: string[];
    curLine: string;
    wasteType: WasteType;
  }

  const condition = reactive<Condition>({
    curDateType: '日',
    dateRange: [],
    curLine: '酸轧',
    wasteType: 'reason',
  });

  const typeMap: Record<string, string> = {
    酸轧: 'TB_YIELD_TCM',
    镀锌: 'TB_YIELD_CGL',
    连退1630: 'TB_YIELD_CAL1630',
    连退2150: 'TB_YIELD_CAL2150',
    重卷1870: 'TB_YIELD_RCL1870',
    重卷1630: 'TB_YIELD_RCL1630',
    重卷2150: 'TB_YIELD_RCL2150',
  };

  const dateTypeMap: Record<string, string> = {
    日: 'day',
    周: 'week',
    月: 'month',
  };

  type DateType = '日' | '周' | '月';
  const dateTypes: DateType[] = ['日', '月']; //'周',
  const wasteTypes: WasteType[] = ['reason', 'steelGrade'];
  const lines: string[] = ['酸轧', '连退1630', '连退2150', '镀锌', '重卷1630', '重卷2150', '重卷1870'];
  const wasteInfo = ref([
    { name: '切头', total: '2000000', current: '1321038' },
    { name: '切头', total: '2000000', current: '1221038' },
    { name: '切头', total: '2000000', current: '1121038' },
    { name: '切头', total: '2000000', current: '1021038' },
    { name: '切头', total: '2000000', current: '1221038' },
    { name: '切头', total: '2000000', current: '1121038' },
    { name: '切头', total: '2000000', current: '1021038' },
  ]);

  const headerButtonClass = computed(() => (line: string) => {
    return line === condition.curLine ? 'is-active' : 'is-default';
  });

  const curLineChange = async (line: string) => {
    condition.curLine = line;
    await nextTick();
    fetchData();
  };

  const DATE_RANGE_CALCULATOR: Record<
    DateType,
    () => [string, string] // 函数返回 [开始日期, 结束日期]
  > = {
    日: () => {
      const today = dayjs().format('YYYY-MM-DD');
      return [today, today]; // 日：开始=结束=今天
    },
    周: () => {
      const current = dayjs();
      return [
        current.startOf('week').format('YYYY-MM-DD'), // 本周第一天
        current.endOf('week').format('YYYY-MM-DD'), // 本周最后一天
      ];
    },
    月: () => {
      const current = dayjs();
      return [
        current.startOf('month').format('YYYY-MM-DD'), // 本月第一天
        current.endOf('month').format('YYYY-MM-DD'), // 本月最后一天
      ];
    },
  };

  const dateTypeClick = (dateType: DateType) => {
    condition.curDateType = dateType;
    const dateRange = DATE_RANGE_CALCULATOR[dateType]();
    dateChange(dateRange);
  };

  const dateChange = async (val: string[]) => {
    condition.dateRange = val;
    await nextTick();
    fetchData();
  };

  const wasteTypeClick = async (wasteType: WasteType) => {
    condition.wasteType = wasteType;
    await nextTick();
    fetchData();
  };

  const tableData = ref([]);

  // ------------------------------------- 图数据 ---------------------------------------------
  const graphData = reactive({
    barData: {
      x: [],
      y1: [],
      min: computed(() => {
        const { min } = getMinMaxWithHalf(graphData.barData.y1);
        return min;
      }),
      max: computed(() => {
        const { max } = getMinMaxWithHalf(graphData.barData.y1);
        return max;
      }),
      config: {
        barWidth: 16, // 🔥 目标 barWidth=15
        diamond: {
          size: [18, 11], // 钻石大小：[宽度=15+2, 高度≈15/1.625]
          offset1: ['-132%', '-40%'], // 第一个钻石（有第二个柱体）偏移
          offset2: ['-42%', '-40%'], // 第二个钻石偏移（水平百分比同步减小）
        },
        barGap: '5%', // 柱体间距（同步缩小，避免空隙过大）
      },
    },
    lineData: {
      x: [],
      y1: [],
      min: computed(() => {
        const { min } = getMinMaxWithHalf(graphData.lineData.y1);
        return min;
      }),
      max: computed(() => {
        const { max } = getMinMaxWithHalf(graphData.lineData.y1);
        return max;
      }),
    },
  });

  const getTrendYield = async () => {
    try {
      const type = typeMap[condition.curLine] || 'TB_YIELD_TCM';
      let startTime = condition.dateRange[0],
        endTime = condition.dateRange[1];
      const params = { type, startTime, endTime, dateType: dateTypeMap[condition.curDateType] };
      const res = await ActualPerformanceRollDeviationApi.getCompleteFlowData(params);
      const arr = Array.isArray(res?.data?.data) ? res.data.data : [];
      graphData.lineData.x = arr.map((i: any) => i.t);
      graphData.lineData.y1 = arr.map((i: any) => (i.yield != null ? (Number(i.yield) * 100).toFixed(2) : ''));
    } catch (error) {
      graphData.lineData.x = [];
      graphData.lineData.y1 = [];
      console.error('获取数据失败');
      throw error;
    }
  };

  const fetchTeamYield = async () => {
    const type = typeMap[condition.curLine] || 'TB_YIELD_TCM';
    let startTime = condition.dateRange[0],
      endTime = condition.dateRange[1];
    const params = { type, startTime, endTime, dateType: dateTypeMap[condition.curDateType] };
    try {
      const res = await ActualPerformanceRollDeviationApi.getCompleteFlowCrewData(params);
      const arr = Array.isArray(res?.data?.data) ? res.data.data : [];
      graphData.barData.x = arr.map((i: any) => '班组' + (i.crew || ''));
      graphData.barData.y1 = arr.map((i: any) => (i.yield != null ? (Number(i.yield) * 100).toFixed(2) : '0'));

      // 同时获取规格数据用于表格显示
      const speciRes = await ActualPerformanceRollDeviationApi.getCompleteFlowSpeciData(params);
      const speciArr = Array.isArray(speciRes?.data?.data) ? speciRes.data.data : [];
      tableData.value = speciArr;
    } catch (e) {
      graphData.barData.y1 = [];
      graphData.barData.x = [];
      tableData.value = [];
    }
  };

  const fetchData = async () => {
    try {
      await Promise.all([getTrendYield(), fetchTeamYield()]);
      ElMessage({
        message: '数据获取成功',
        type: 'success',
        duration: 2000,
      });
    } catch (err: any) {
      console.error('数据获取失败:', err);
      ElMessage({
        message: `数据获取失败：${err?.message || '未知错误'}`,
        type: 'error',
        duration: 2000,
      });
    }
  };

  onMounted(() => {
    // 初始化时间
    const start = dayjs().subtract(6, 'day').format('YYYY-MM-DD');
    const end = dayjs().format('YYYY-MM-DD');
    condition.dateRange = [start, end];
    fetchData();
  });

  /**
   * 处理数字数组，返回指定规则的最小/最大值（xx.5形式）
   * @param arr 输入的数字数组
   * @returns 包含min和max的对象，值为最接近的xx.5形式
   */
  function getMinMaxWithHalf(arr: number[]): { min: number; max: number } {
    // 处理空数组情况
    if (arr.length === 0) {
      return { min: 0, max: 100 };
    }

    // 1. 获取数组原始的最小值和最大值
    const originalMin = Math.min(...arr);
    const originalMax = Math.max(...arr);

    // 2. 最小值减1，最大值加1
    const minAfterMinus = originalMin - 1;
    const maxAfterPlus = originalMax + 1;

    // 3. 将处理后的值转换为xx.5形式
    const resultMin = toNearestHalf(minAfterMinus);
    const resultMax = toNearestHalf(maxAfterPlus);

    return { min: resultMin, max: resultMax };
  }

  /**
   * 辅助函数：将数字转换为最接近的xx.5形式
   * @param num 待处理的数字
   * @returns 最接近的xx.5形式的数字
   */
  const toNearestHalf = (num: number): number => {
    // 获取整数部分（向下取整）
    const integerPart = Math.floor(num);
    // 生成两个候选值：当前整数部分+0.5 和 下一个整数部分+0.5
    const candidate1 = integerPart + 0.5;
    const candidate2 = integerPart + 1.5;
    // 计算当前数字与两个候选值的距离
    const distance1 = Math.abs(num - candidate1);
    const distance2 = Math.abs(num - candidate2);
    // 返回距离更近的候选值（距离相等时取较小的）
    return distance1 <= distance2 ? candidate1 : candidate2;
  };
</script>
<style lang="less" scoped>
  .home {
    background: url(/src/assets/images/yield/yield-bg.png);
  }
  .page-layout {
    display: flex;
    flex-direction: column;
    min-height: 94vh;
    gap: 1vh;
    margin-top: -10vh;
    padding: 20px;
    width: 99.5%;
  }

  .area {
    background-color: rgba(12, 37, 87, 0.5);
    border: 1px solid;
    border-image: linear-gradient(180deg, rgba(19, 163, 255, 0.25), rgba(19, 163, 255, 0.25), rgba(19, 163, 255, 0.4)) 1 1;
    padding: 12px;
    opacity: 0.9;
  }

  .title {
    display: flex;
    align-items: center;
    margin-right: auto;
  }

  .title img {
    margin-top: -0.6vh;
  }

  .title span {
    font-weight: 700;
    font-size: 16px;
    font-family: '江城斜黑体', sans-serif;
    background-image: linear-gradient(to bottom, rgba(49, 190, 255, 1), rgba(255, 255, 255, 1), rgba(255, 255, 255, 1));
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    filter: drop-shadow(0 0 2px rgba(48, 117, 211, 0.8)) drop-shadow(0 0 3px rgba(48, 117, 211, 0.6));
  }

  :deep(.date-picker.el-date-editor) {
    width: 226px;
    height: 28px;
    background: #0d1845;
    border: 1px solid #0c83cf;
    box-shadow: 0 0 0 1px #0d1845 inset;
  }

  :deep(.date-picker .el-range-input) {
    background-color: transparent !important;
    color: #fff !important;
    font-weight: 400;
    font-family: 'Source Han Sans', sans-serif;
  }

  :deep(.date-picker .el-range-separator) {
    background-color: transparent !important;
    color: #fff !important;
    font-weight: 400;
    font-family: 'Source Han Sans', sans-serif;
  }

  :deep(.date-picker .el-input__icon) {
    color: #fff !important;
  }

  .buttons {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.5vw;

    button {
      width: 46px;
      height: 28px;
      color: rgba(216, 240, 255, 0.5);
      text-shadow: 0px 0px 4px #0091ff;
      font-weight: 400;
      font-size: 14px;
      background: linear-gradient(180deg, rgba(15, 74, 159, 0) 0%, rgba(17, 75, 160, 0.95) 100%);
      border: 1px solid rgba(0, 45, 89, 0.8);
      font-family: 'Source Han Sans-Regular', sans-serif;
      cursor: pointer;
      text-align: center;
    }

    button.is-active {
      color: #d8f0ff;
      text-shadow:
        0px 0px 10px #0091ff,
        0px 0px 4px #0091ff;
      background: linear-gradient(180deg, rgba(15, 74, 159, 0) 0%, rgba(17, 75, 160, 0.95) 100%);
      border: 1px solid rgba(30, 123, 214, 0.8);
    }
  }

  .title-head {
    display: flex;
    flex-wrap: nowrap;
    // justify-content: space-between;
    align-items: center;
    width: 98%;
    margin-top: -5px;
  }

  .progress {
    display: flex;
    flex-direction: column;
    gap: 17px;
  }

  .progress-container {
    display: flex;
    flex-direction: column;
    gap: 9px;
    width: 98%;
    margin-left: 1%;

    .progress-info {
      display: flex;
      flex-wrap: nowrap;
      justify-content: space-between;
      align-items: center;
      width: 99%;
      margin-left: 0.5%;
      font-family: 'Source Han Sans-Medium', sans-serif;
      font-weight: 500;
      font-size: 14px;
      color: #fff;
      line-height: 12px;

      span.progress-num {
        font-family: 'DIN Condensed-Bold', sans-serif;
        font-weight: 700;
        font-size: 16px;
      }
    }

    .progress-bar {
      display: flex;
      position: relative;
      height: 16px;
      width: 100%;
      margin-bottom: 2vh;

      .progress-background {
        height: 16px;
        width: 100%;
        background-color: rgba(18, 40, 89, 0.8);
        z-index: 11;
      }

      .progress-inner {
        position: absolute;
        z-index: 12;
        height: 100%;
        width: 0%;
        background: linear-gradient(-90deg, #01fffd 0%, #0379ff 100%);
        animation: progressGrow 1s cubic-bezier(0.4, 0, 0.2, 1) 0.2s forwards;
      }

      @keyframes progressGrow {
        from {
          width: 0%;
        }
        to {
          width: var(--target-width);
        }
      }
    }
  }

  :deep(.el-radio-button__inner) {
    color: rgba(216, 240, 255, 0.5);
    text-shadow: 0px 0px 4px #0091ff;
    font-weight: 400;
    font-size: 12px;
    background-color: transparent;
    border: 1px solid rgba(30, 123, 214, 0.3);
  }

  :deep(.el-radio-button.is-active .el-radio-button__original-radio:not(:disabled) + .el-radio-button__inner) {
    color: #d8f0ff;
    text-shadow:
      0px 0px 10px #0091ff,
      0px 0px 4px #0091ff;
    font-weight: 400;
    font-size: 12px;
    background-color: transparent;
    border: 1px solid rgba(30, 123, 214, 0.8);
  }

  :deep(.el-radio-button:first-child .el-radio-button__inner) {
    border-left: 1px solid rgba(30, 123, 214, 0.3);
  }

  :deep(.el-table) {
    background-color: transparent;
    --el-table-border: none;
    --el-table-border-color: transparent;
    color: white;
    --el-table-row-hover-bg-color: unset;

    :deep(.el-table__row:nth-child(odd)) {
      background-color: #223671;
    }
  }

  :deep(.el-table__inner-wrapper::before) {
    left: 0;
    bottom: 0;
    width: 100%;
    height: 0;
  }
  :deep(.el-table__row:nth-child(odd)) {
    background-color: rgba(6, 13, 47, 0.5);
  }
  :deep(.el-table__row:nth-child(even)) {
    background-color: rgba(21, 29, 81, 0.5);
  }

  :deep(.el-table th),
  :deep(.el-table tr),
  :deep(.el-table td) {
    background-color: transparent;
  }

  // -------------------------------------------------------------------------

  .head-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    .header-img {
      margin-top: 1vh;
      // width: 537px;
      height: 51px;
      img {
        transform: rotate(180deg);
        z-index: 2;
      }
    }

    .header-condition {
      display: flex;
      flex-wrap: nowrap;
      z-index: 3;
      width: 100%;
      align-items: center;

      .line {
        display: flex;
        align-items: center;
        margin-left: auto;

        .line-item {
          height: 32px;
          width: 128px;
          display: flex;
          align-items: center;
          justify-content: center;
          cursor: pointer;
        }

        .is-active {
          background: url(/src/assets/images/yield/button-bg-active.png);
          background-size: contain;
          font-family: 'Source Han Sans', sans-serif;
          font-weight: 700;
          font-size: 16px;
          color: #ffffff;
          text-shadow: 1px 1px 1px rgba(6, 17, 54, 0.3);
          text-align: center;
        }

        .is-default {
          background: url(/src/assets/images/yield/button-bg-default.png);
          background-size: contain;
          font-family: 'Source Han Sans', sans-serif;
          font-weight: 400;
          font-size: 16px;
          color: #c4c4c4;
          text-align: center;
        }
      }

      .date {
        display: flex;
        align-items: center;
        margin-left: 9vw;
        gap: 1vw;
      }
    }
  }

  .main-container {
    height: 552px;
    gap: 8px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);

    .trend-card {
      height: 552px;
    }

    .crew-card {
      height: 552px;
    }

    .waste-card {
      height: 552px;
    }
  }
</style>
